/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bff.core.action.retrievedefault;

import com.inspur.edp.bef.api.lcp.IStandardLcp;
import com.inspur.edp.bff.api.dataprocessor.IDataConvertor;
import com.inspur.edp.bff.api.dataprocessor.IDefaultValueConvertor;
import com.inspur.edp.bff.api.extend.IBffEntityExtend;
import com.inspur.edp.bff.api.extend.IBffManagerExtend;
import com.inspur.edp.bff.api.manager.IFSManager;
import com.inspur.edp.bff.entity.defaultvalue.VoDefaultValue;
import com.inspur.edp.bff.spi.AbstractDataConvertor;
import com.inspur.edp.bff.spi.AbstractFSAction;
import com.inspur.edp.bff.spi.defaultvalue.DefaultValueUtil;
import com.inspur.edp.cef.api.changeListener.EntityDataChangeListener;
import com.inspur.edp.cef.api.dataType.entity.ICefEntity;
import com.inspur.edp.cef.entity.accessor.entity.IEntityAccessor;
import com.inspur.edp.cef.entity.changeset.IChangeDetail;
import com.inspur.edp.cef.entity.changeset.ModifyChangeDetail;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.entity.entity.IEntityData;
import lombok.var;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class RetrieveDefaultChildWithDefaultValueAtion extends AbstractFSAction<IEntityData> {

    private ArrayList<String> nodeCodes;
    private ArrayList<String> lierachyIds;
    private VoDefaultValue defaultValue;

    public RetrieveDefaultChildWithDefaultValueAtion(ArrayList<String> nodeCodes, ArrayList<String> lierachyIds, VoDefaultValue defaultValue) {
        this.nodeCodes = nodeCodes;
        this.lierachyIds = lierachyIds;
        this.defaultValue = defaultValue;

    }


    @Override
    protected void execute() {

        IStandardLcp lcp = getLcp();
        IFSManager bffManager = getContext().getBffManager();
        Map<String, Object> beDefaultValue = DefaultValueUtil.transVoDefaultValueToBe(lcp, getContext(), defaultValue, nodeCodes);
        IEntityData beData = lcp.retrieveDefaultChild(nodeCodes, lierachyIds, beDefaultValue);
        Object tempVar = bffManager.createChildData(nodeCodes.get(nodeCodes.size() - 1), "");
        IEntityAccessor vmAccessor = (IEntityAccessor) ((tempVar instanceof IEntityAccessor) ? tempVar : null);
        IEntityData voData = (IEntityData) ((vmAccessor.getInnerData() instanceof IEntityData) ? vmAccessor.getInnerData() : null);

        transBeDataToVoData(beData, voData);
        //region extend
        dealExtendMapping(voData, beData);


        vmAccessor.setInnerData(voData);

        dealDefaultValue(vmAccessor);
        IEntityData result = (IEntityData) ((vmAccessor.getInnerData() instanceof IEntityData) ? vmAccessor.getInnerData() : null);

        setResult(result);
    }

    private IDefaultValueConvertor getDefaultValueConvertor() {

        return getContext().getDefaultValueConvertor();
    }

    private IEntityData transBeDataToVoData(IEntityData beData, IEntityData voData) {

        IDataConvertor dataConvertor = getDataConvertor(nodeCodes);
        if (dataConvertor != null)

            dataConvertor.convertFromBEData(beData, voData);

        return voData;
    }

    private void dealDefaultValue(IEntityAccessor vmAccessor) {

        IEntityData voData = (IEntityData) ((vmAccessor.getInnerData() instanceof IEntityData) ? vmAccessor.getInnerData() : null);

        EntityDataChangeListener listener = EntityDataChangeListener.createInstance();
        listener.registListener((ICefData) ((vmAccessor instanceof ICefData) ? vmAccessor : null));
        ICefEntity entinty = getEntity(voData.getID());
        entinty.assignDefaultValue(vmAccessor);


        IChangeDetail defalutChange = listener.getChange();
        if (defalutChange != null) {
            ModifyChangeDetail beChange = getChangeDetail((ModifyChangeDetail) ((defalutChange instanceof ModifyChangeDetail) ? defalutChange : null));
            getContext().getBffManager().modify(beChange);
        }
    }

    private void dealExtendMapping(IEntityData voData, IEntityData beData) {
        var extList = getContext().getExtList();
        if (extList == null || extList.size() < 1)
            return;
        for (var ext : extList) {
            IBffEntityExtend entityExtend = getChildEntityExtend(ext);
            if (entityExtend != null)
                entityExtend.mapData2Vo(voData, beData);
        }
    }

    private IBffEntityExtend getChildEntityExtend(IBffManagerExtend mgrExtend) {
        IBffEntityExtend entityExtend = mgrExtend.getDataTypeExtend();
        for (String nodeCode : nodeCodes) {
            entityExtend = entityExtend.getChildEntity(nodeCode);
            if (entityExtend == null)
                break;
        }
        return entityExtend;
    }

    private ModifyChangeDetail getChangeDetail(ModifyChangeDetail defaultChange) {
        IChangeDetail tempVar = defaultChange.clone();

        ModifyChangeDetail currentChange = (ModifyChangeDetail) ((tempVar instanceof ModifyChangeDetail) ? tempVar : null);
        for (int i = lierachyIds.size() - 1; i >= 0; i--) {

            String nodeCode = nodeCodes.get(i);
            ModifyChangeDetail change = new ModifyChangeDetail(lierachyIds.get(i));
            HashMap<String, IChangeDetail> childChange = new HashMap<String, IChangeDetail>();
            childChange.put(currentChange.getDataID(), currentChange);
            change.getChildChanges().put(nodeCode, childChange);
            IChangeDetail tempVar2 = change.clone();
            currentChange = (ModifyChangeDetail) ((tempVar2 instanceof ModifyChangeDetail) ? tempVar2 : null);
        }

        return currentChange;
    }

    private ICefEntity getEntity(String childId) {
        ICefEntity currentEntity = getContext().getBffManager().createEntity(lierachyIds.get(0));
        for (int i = 0; i < nodeCodes.size(); i++) {
            currentEntity = currentEntity.getChildEntity(nodeCodes.get(i), i == nodeCodes.size() - 1 ? childId : lierachyIds.get(i + 1));
        }

        return currentEntity;
    }

    private IDataConvertor getDataConvertor(ArrayList<String> nodeCodes) {
        IDataConvertor tempVar = getContext().getDataConvertor();
        AbstractDataConvertor rootConvertor = (AbstractDataConvertor) ((tempVar instanceof AbstractDataConvertor) ? tempVar : null);
        if (nodeCodes.isEmpty()) {
            return rootConvertor;
        }
        AbstractDataConvertor currentConvertor = rootConvertor;
        for (int i = 0; i < nodeCodes.size(); i++) {
            currentConvertor = (AbstractDataConvertor) currentConvertor.getChildConvertor(nodeCodes.get(i));
            if (currentConvertor == null)
                break;
        }
        return currentConvertor;
    }

}
